import os
import pygame
from pygame.locals import *
from pygame import *
from classes import *
from config import config
from guiinput import guiinput

class vkeyboard:
    def __init__(self, application):
        self.__vkeyboardlist = []
        # CONFIG
        jc = config('joywm.xml')
        jkl = jc.conf.get('keyboard')
        vc = config('keyboard/' + jkl + '.xml')
        self.__layout = 'normal'
        self.__shift = False
        # KEYBOARD FRAME
        kul = loadimage(application.themepath + '/widgets/frame_upperleft.png', application.cubex / 2, application.cubey / 2)
        kul.rect.x = 7 * application.cubex - application.cubex / 2
        kul.rect.y = application.cubey * 19 - application.cubey / 2
        kur = loadimage(application.themepath + '/widgets/frame_upperright.png', application.cubex / 2, application.cubey / 2)
        kur.rect.x = application.cubex * 25
        kur.rect.y = application.cubey * 19 - application.cubey / 2
        kup = loadimage(application.themepath + '/widgets/frame_upper.png', application.cubex * 18, application.cubey / 2)
        kup.rect.x = application.cubex * 7
        kup.rect.y = application.cubey * 19 - application.cubey / 2
        kle = loadimage(application.themepath + '/widgets/frame_left.png', application.cubex / 2, application.cubey * 5)
        kle.rect.x =  7 * application.cubex - application.cubex / 2
        kle.rect.y = application.cubey * 19
        kri = loadimage(application.themepath + '/widgets/frame_right.png', application.cubex / 2, application.cubey * 5)
        kri.rect.x = application.cubex * 25
        kri.rect.y = application.cubey * 19
        self.__vkeyboardlist.append(kul)
        self.__vkeyboardlist.append(kur)
        self.__vkeyboardlist.append(kup)
        self.__vkeyboardlist.append(kle)
        self.__vkeyboardlist.append(kri)
        # TEXTWINDOW FRAME
        tul = loadimage(application.themepath + '/widgets/frame_upperleft.png', application.cubex / 2, application.cubey / 2)
        tul.rect.x = 7 * application.cubex - application.cubex / 2
        tul.rect.y = application.cubey * 16 - application.cubey / 2
        tur = loadimage(application.themepath + '/widgets/frame_upperright.png', application.cubex / 2, application.cubey / 2)
        tur.rect.x = application.cubex * 25
        tur.rect.y = application.cubey * 16 - application.cubey / 2
        tup = loadimage(application.themepath + '/widgets/frame_upper.png', application.cubex * 18, application.cubey / 2)
        tup.rect.x = application.cubex * 7
        tup.rect.y = application.cubey * 16 - application.cubey / 2
        tle = loadimage(application.themepath + '/widgets/frame_left.png', application.cubex / 2, application.cubey * 1)
        tle.rect.x =  7 * application.cubex - application.cubex / 2
        tle.rect.y = application.cubey * 16
        tri = loadimage(application.themepath + '/widgets/frame_right.png', application.cubex / 2, application.cubey * 1)
        tri.rect.x = application.cubex * 25
        tri.rect.y = application.cubey * 16
        tbl = loadimage(application.themepath + '/widgets/frame_bottomleft.png', application.cubex / 2, application.cubey / 2)
        tbl.rect.x =  7 * application.cubex - application.cubex / 2
        tbl.rect.y = application.cubey * 17
        tbr = loadimage(application.themepath + '/widgets/frame_bottomright.png', application.cubex / 2, application.cubey / 2)
        tbr.rect.x = application.cubex * 25
        tbr.rect.y = application.cubey * 17
        tbo = loadimage(application.themepath + '/widgets/frame_bottom.png', application.cubex * 18, application.cubey / 2)
        tbo.rect.x = application.cubex * 7
        tbo.rect.y = application.cubey * 17
        self.__vkeyboardlist.append(tul)
        self.__vkeyboardlist.append(tur)
        self.__vkeyboardlist.append(tup)
        self.__vkeyboardlist.append(tle)
        self.__vkeyboardlist.append(tri)
        self.__vkeyboardlist.append(tbl)
        self.__vkeyboardlist.append(tbr)
        self.__vkeyboardlist.append(tbo)
        # KEYBOARD BACKGROUND
        kbackground = loadimage(application.themepath + '/widgets/vkeyboard_background.png', application.cubex * 18, application.cubey * 5)
        kbackground.rect.x = application.cubex * 7
        kbackground.rect.y = application.cubey * 19
        self.__vkeyboardlist.append(kbackground)
        # SELECTOR
        self.__selectord = loadimage(application.themepath + '/widgets/vkeyboard_selectb.png', application.cubex, application.cubey)
        self.__selectord.rect.x = application.cubex * 7
        self.__selectord.rect.y = application.cubey * 19
        self.__vkeyboardlist.append(self.__selectord)
        self.__selectoru = loadimage(application.themepath + '/widgets/vkeyboard_selectu.png', application.cubex, application.cubey)
        self.__selectoru.rect.x = application.cubex * 7
        self.__selectoru.rect.y = application.cubey * 19
        self.__vkeyboardlist.append(self.__selectoru)
        self.__selectorl = loadimage(application.themepath + '/widgets/vkeyboard_selectl.png', application.cubex, application.cubey)
        self.__selectorl.rect.x = application.cubex * 7
        self.__selectorl.rect.y = application.cubey * 19
        self.__vkeyboardlist.append(self.__selectorl)
        self.__selectorr = loadimage(application.themepath + '/widgets/vkeyboard_selectr.png', application.cubex, application.cubey)
        self.__selectorr.rect.x = application.cubex * 7
        self.__selectorr.rect.y = application.cubey * 19
        self.__vkeyboardlist.append(self.__selectorr)
        self.__selposx = 0
        self.__selposy = 0
        self.__allselpos = {}
        self.__normalselpos = {}
        self.__shiftselpos = {}
        self.__tmpinput = ''
        self.userinput = ''
        # KEYBOARD LAYOUTS
        self.__normallayout = []
        self.__shiftlayout = []
        self.__bigkeys = {}
        il = {}
        for lo in ['normal', 'shift']:
            for x in range(0, len(vc.conf[lo].keys())):
                letter = vc.conf[lo].keys()[x]
                if letter != application.keyboard and letter != '/' + application.keyboard:
                    pos = vc.conf[lo][letter]
                    # XPOS
                    sep = pos.find(',')
                    xpos = int(pos[0:sep])
                    pos = pos[sep + 1:len(pos)]
                    # YPOS
                    sep = pos.find(',')
                    ypos = int(pos[0:sep])
                    pos = pos[sep + 1:len(pos)]
                    # WIDTH
                    sep = pos.find(',')
                    width = int(pos[0:sep])
                    # HEIGHT
                    height = int(pos[sep + 1:len(pos)])
                    if width != 1 or height != 1:
                        for i in range(xpos, xpos + width):
                            for j in range(ypos, ypos + height):
                                self.__bigkeys[(i,j)] = (letter, xpos, ypos)
                    # SOMETIME WE HAVE SPECIAL LETTERS
                    if letter == 'gt': letter = '<'
                    if letter == 'lt': letter = '>'
                    # SELECTOR POSITIONS
                    poskey = (xpos, ypos)
                    if lo == 'normal': self.__normalselpos[poskey] = (letter, width, height)
                    if lo == 'shift': self.__shiftselpos[poskey] = (letter, width, height)
                    # LAOD LETTERS
                    li = False
                    if letter == 'RShift' or letter == 'LShift' or letter == 'Esc' or letter == 'Back' or letter == 'Enter' or letter == 'Space':
                        if os.path.exists(application.themepath + '/widgets/vkeyboard_' + letter + '.png') == True:
                            li = True
                    if li == False:
                        ll = loadletter(letter, application)
                        ll.rect.x = xpos * application.cubex + 7 * application.cubex
                        ll.rect.x = ll.rect.x + (application.cubex - ll.rect.width) / 2
                        ll.rect.y = (ypos + 19 ) * application.cubey
                        if lo == 'normal': self.__normallayout.append(ll)
                        if lo == 'shift': self.__shiftlayout.append(ll)
                    else:
                        if il.has_key(letter) != True:
                            ll = loadimage(application.themepath + '/widgets/vkeyboard_' + letter + '.png', width * application.cubex, height * application.cubey)
                            ll.rect.x = xpos * application.cubex + 7 * application.cubex
                            ll.rect.y = (ypos + 19 ) * application.cubey
                            self.__normallayout.append(ll)
                            self.__shiftlayout.append(ll)
                            il[letter] = True
        self.__allselpos['normal'] = self.__normalselpos
        self.__allselpos['shift'] = self.__shiftselpos
        # RENDER
        self.__vkeyboardrender = pygame.sprite.OrderedUpdates(self.__vkeyboardlist)
        self.__normallayoutrender = pygame.sprite.OrderedUpdates(self.__normallayout)
        self.__shiftlayoutrender = pygame.sprite.OrderedUpdates(self.__shiftlayout)

    def show(self, application):
        # GET CONFIG FOR SPECIAL KEYS
        sc = config('keyboard/special.xml')
        # PREPARE SOME STUFF
        if self.__tmpinput == '': self.userinput == ''
        self.__layout = 'normal'
        self.__shift = False
        # TEXTWINDOW
        twlist = []
        tbackground = loadimage(application.themepath + '/widgets/vkeyboard_background.png', application.cubex * 18, application.cubey * 1)
        tbackground.rect.x = application.cubex * 7
        tbackground.rect.y = application.cubey * 16
        twlist.append(tbackground)
        if self.__tmpinput != '':
            ti = loadletter(self.__tmpinput, application)
            ti.rect.x = application.cubex * 7
            ti.rect.y = application.cubex * 16
            twlist.append(ti)
        twrender = pygame.sprite.OrderedUpdates(twlist)
        twrender.draw(pygame.display.get_surface())
        # REPRINT SELECTOR
        poskey = (self.__selposx, self.__selposy)
        self.__reprintselector(poskey, application)

        key = guiinput()
        while 1:
            key.getkey()

            # KEYBOARD
            if key.device == 'kbd':

                # ABORT
                if key.keyname == 'escape':
                    self.__hide(application)
                    break
                elif key.keyname == 'return':
                    self.userinput = self.__tmpinput
                    self.__tmpinput = ''
                    self.__hide(application)
                    break
                elif key.keyname == 'backspace':
                    self.__backspace(tbackground, application)

                # GET INPUT
                vc = config('keyboard/' + application.keyboard + '.xml')
                if key.keyname == 'space': key.keyname = 'Space'
                if vc.conf[self.__layout].has_key(key.keyname) == True:
                    pos = vc.conf[self.__layout][key.keyname]
                    # XPOS
                    sep = pos.find(',')
                    xpos = int(pos[0:sep])
                    pos = pos[sep + 1:len(pos)]
                    # YPOS
                    sep = pos.find(',')
                    ypos = int(pos[0:sep])
                    pos = pos[sep + 1:len(pos)]
                    # WIDTH
                    sep = pos.find(',')
                    width = int(pos[0:sep])
                    # HEIGHT
                    height = int(pos[sep + 1:len(pos)])
                    poskey = (xpos, ypos)
                    self.__selposx = xpos
                    self.__selposy = ypos
                    twlist = []
                    twlist.append(tbackground)
                    letter = key.keyname
                    if letter == 'Space': letter = ' '
                    bakinput = self.__tmpinput
                    self.__tmpinput = self.__tmpinput + letter
                    ti = loadletter(self.__tmpinput, application)
                    if ti.rect.width > tbackground.rect.width:
                        self.__tmpinput = bakinput
                        ti = loadletter(self.__tmpinput, application)
                    ti.rect.x = application.cubex * 7
                    ti.rect.y = application.cubex * 16
                    twlist.append(ti)
                    twrender = pygame.sprite.OrderedUpdates(twlist)
                    twrender.draw(pygame.display.get_surface())
                    self.__reprintselector(poskey, application)
                    pygame.display.flip()

            # JOYSTICK
            if key.device[0:2] == 'js':

                # ABORT
                if key.keyname == 'b':
                    self.__hide(application)
                    break

                # DELETE LAST LETTER (BACKSPACE)
                if key.keyname == 'x':
                    self.__backspace(tbackground, application)

                # SWITCH TO SHIFT
                if key.keyname == 'y':
                    if self.__shift == False:
                        self.__shift = True
                        self.__layout = 'shift'
                        self.__reprintselector(poskey, application)
                    else:
                        self.__shift = False
                        self.__layout = 'normal'
                        self.__reprintselector(poskey, application)

                # ADD INPUT
                if key.keyname == 'a':
                    poskey = (self.__selposx, self.__selposy)
                    letter = self.__allselpos[self.__layout][poskey][0]
                    if letter == 'Back':
                        self.__backspace(tbackground, application)
                    elif letter == 'LShift' or letter == 'RShift':
                        if self.__shift == False:
                            self.__shift = True
                            self.__layout = 'shift'
                            self.__reprintselector(poskey, application)
                        else:
                            self.__shift = False
                            self.__layout = 'normal'
                            self.__reprintselector(poskey, application)
                    elif letter == 'Space':
                        self.__tmpinput = self.__tmpinput + ' '
                    elif letter == 'Enter':
                        self.userinput = self.__tmpinput
                        self.__tmpinput = ''
                        self.__hide(application)
                        break
                    elif letter == 'Esc':
                        self.userinput = ''
                        self.__hide(application)
                        break
                    else:
                        twlist = []
                        twlist.append(tbackground)
                        bakinput = self.__tmpinput
                        self.__tmpinput = self.__tmpinput + letter
                        ti = loadletter(self.__tmpinput, application)
                        if ti.rect.width > tbackground.rect.width:
                            self.__tmpinput = bakinput
                            ti = loadletter(self.__tmpinput, application)
                        ti.rect.x = application.cubex * 7
                        ti.rect.y = application.cubex * 16
                        twlist.append(ti)
                        twrender = pygame.sprite.OrderedUpdates(twlist)
                        twrender.draw(pygame.display.get_surface())
                        pygame.display.flip()

                # UP
                if key.keyname == 'up':
                    self.__selposy = self.__selposy - 1
                    if self.__selposy < 0: self.__selposy = 4
                    poskey = (self.__selposx, self.__selposy)
                    while self.__allselpos[self.__layout].has_key(poskey) == False:
                        if self.__bigkeys.has_key(poskey):
                            self.__selposx = self.__bigkeys[poskey][1]
                            self.__selposy = self.__bigkeys[poskey][2]
                            poskey = (self.__selposx, self.__selposy)
                            break
                        self.__selposy = self.__selposy - 1
                        if self.__selposy < 0: self.__selposy = 4
                        poskey = (self.__selposx, self.__selposy)
                    self.__reprintselector(poskey, application)

                # DOWN
                if key.keyname == 'down':
                    tmpposkey = (self.__selposx, self.__selposy)
                    self.__selposy = self.__selposy + 1
                    if self.__selposy > 4: self.__selposy = 0
                    poskey = (self.__selposx, self.__selposy)
                    while self.__allselpos[self.__layout].has_key(poskey) == False:
                        if self.__bigkeys.has_key(poskey):
                            newselposx = self.__bigkeys[poskey][1]
                            newselposy = self.__bigkeys[poskey][2]
                            newposkey = (newselposx, newselposy)
                            if newposkey != tmpposkey:
                                self.__selposx = newselposx
                                self.__selposy = newselposy
                                poskey = newposkey
                                break
                        self.__selposy = self.__selposy + 1
                        if self.__selposy > 4: self.__selposy = 0
                        poskey = (self.__selposx, self.__selposy)
                    self.__reprintselector(poskey, application)

                # LEFT
                if key.keyname == 'left':
                    self.__selposx = self.__selposx - 1
                    if self.__selposx < 0: self.__selposx = 17
                    poskey = (self.__selposx, self.__selposy)
                    while self.__allselpos[self.__layout].has_key(poskey) == False:
                        if self.__bigkeys.has_key(poskey):
                            self.__selposx = self.__bigkeys[poskey][1]
                            self.__selposy = self.__bigkeys[poskey][2]
                            poskey = (self.__selposx, self.__selposy)
                            break
                        self.__selposx = self.__selposx - 1
                        if self.__selposx < 0: self.__selposx = 17
                        poskey = (self.__selposx, self.__selposy)
                    self.__reprintselector(poskey, application)

                # RIGHT
                if key.keyname == 'right':
                    tmpposkey = (self.__selposx, self.__selposy)
                    self.__selposx = self.__selposx + 1
                    if self.__selposx > 17: self.__selposx = 0
                    poskey = (self.__selposx, self.__selposy)
                    while self.__allselpos[self.__layout].has_key(poskey) == False:
                        if self.__bigkeys.has_key(poskey):
                            newselposx = self.__bigkeys[poskey][1]
                            newselposy = self.__bigkeys[poskey][2]
                            newposkey = (newselposx, newselposy)
                            if newposkey != tmpposkey:
                                self.__selposx = newselposx
                                self.__selposy = newselposy
                                poskey = newposkey
                                break
                        self.__selposx = self.__selposx + 1
                        if self.__selposx > 17: self.__selposx = 0
                        poskey = (self.__selposx, self.__selposy)
                    self.__reprintselector(poskey, application)

            # SPECIAL KEYS LIKE F1 ETC (SEE special.xml)
            if sc.conf.has_key(key.keyname):
                twlist = []
                twlist.append(tbackground)
                self.__tmpinput = self.__tmpinput + sc.conf.get(key.keyname)
                ti = loadletter(self.__tmpinput, application)
                ti.rect.x = application.cubex * 7
                ti.rect.y = application.cubex * 16
                twlist.append(ti)
                twrender = pygame.sprite.OrderedUpdates(twlist)
                twrender.draw(pygame.display.get_surface())
                pygame.display.flip()

            key.delete()

    def __reprintselector(self, poskey, application):
        self.__selectord.rect.x = application.cubex * (7 + self.__selposx)
        self.__selectord.rect.y = application.cubey * (19 + self.__selposy + self.__allselpos[self.__layout][poskey][2] - 1)
        self.__selectord.image = pygame.transform.scale(self.__selectord.image, (self.__allselpos[self.__layout][poskey][1] * application.cubex, application.cubey))
        self.__selectoru.rect.x = application.cubex * (7 + self.__selposx)
        self.__selectoru.rect.y = application.cubey * (19 + self.__selposy)
        self.__selectoru.image = pygame.transform.scale(self.__selectoru.image, (self.__allselpos[self.__layout][poskey][1] * application.cubex, application.cubey))
        self.__selectorl.rect.x = application.cubex * (7 + self.__selposx)
        self.__selectorl.rect.y = application.cubey * (19 + self.__selposy)
        self.__selectorl.image = pygame.transform.scale(self.__selectorl.image, (application.cubex, self.__allselpos[self.__layout][poskey][2] * application.cubey))
        self.__selectorr.rect.x = application.cubex * (7 + self.__selposx + self.__allselpos[self.__layout][poskey][1] - 1)
        self.__selectorr.rect.y = application.cubey * (19 + self.__selposy)
        self.__selectorr.image = pygame.transform.scale(self.__selectorr.image, (application.cubex, self.__allselpos[self.__layout][poskey][2] * application.cubey))
        self.__vkeyboardrender.draw(pygame.display.get_surface())
        if self.__layout == 'normal': self.__normallayoutrender.draw(pygame.display.get_surface())
        if self.__layout == 'shift': self.__shiftlayoutrender.draw(pygame.display.get_surface())
        pygame.display.flip()

    def __hide(self, application):
        application.spritegrouprender.draw(pygame.display.get_surface())
        pygame.display.flip()

    def __backspace(self, tbackground, application):
        twlist = []
        twlist.append(tbackground)
        self.__tmpinput = self.__tmpinput[0:len(self.__tmpinput) - 1]
        ti = loadletter(self.__tmpinput, application)
        ti.rect.x = application.cubex * 7
        ti.rect.y = application.cubex * 16
        twlist.append(ti)
        twrender = pygame.sprite.OrderedUpdates(twlist)
        twrender.draw(pygame.display.get_surface())
        pygame.display.flip()
